using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FireStarterModeller.BO;
using FireStarterModeller.Logic.Commands;
using FireStarterModeller.Test.BO;
using Habanero.Base.Exceptions;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic.Commands
{
    [TestFixture]
    public class TestCreateAssemblyCommand
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            TestUtilsLogic.SetupFixture();
        }
        [SetUp]
        public void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        private ICommandFactory CommandFactory
        {
            get { return new CommandFactory(); }
        }

        [Test]
        public void Test_Apply()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            dmSolution.Assemblies.Refresh();
            const string assemblyName = "Assembly2";
            //--------------Assert Preconditions ---------------
            Assert.AreEqual(0, dmSolution.Assemblies.Count);
            //---------------Execute Test ----------------------
            ICommand command = CommandFactory.CreateCreateAssembly(dmSolution, assemblyName);
            command.Apply();

            //---------------Test Result -----------------------
            Assert.AreEqual(1, dmSolution.Assemblies.Count);
            DMAssembly assembly = dmSolution.Assemblies[0];
            Assert.IsFalse(assembly.Status.IsNew);
            Assert.AreEqual(assemblyName, assembly.AssemblyName);
            Assert.AreSame(dmSolution, assembly.Solution);
        }

        [Test]
        public void Test_Apply_Failure()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            const string assemblyName = "Assembly2";
            ICommand command1 = CommandFactory.CreateCreateAssembly(dmSolution, assemblyName);
            command1.Apply();

            ICommand command2 = CommandFactory.CreateCreateAssembly(dmSolution, assemblyName);

            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmSolution.Assemblies.Count);

            //---------------Execute Test ----------------------
            try
            {
                command2.Apply();
                Assert.Fail("Duplicate assembly name should have raised error");
                //---------------Test Result -----------------------
            } catch (BusObjDuplicateConcurrencyControlException ex)
            {
                StringAssert.Contains("Module' already exists ", ex.Message);
            }
            Assert.AreEqual(1, dmSolution.Assemblies.Count);
            //---------------Tear Down -------------------------          
        }


        [Test]
        public void Test_Revert()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            string assemblyName = "Assembly2";
            ICommand command = CommandFactory.CreateCreateAssembly(dmSolution, assemblyName);
            command.Apply();

            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmSolution.Assemblies.Count);
            DMAssembly assembly = dmSolution.Assemblies[0];
            Assert.IsFalse(assembly.Status.IsNew);

            //---------------Execute Test ----------------------
            command.Revert();

            //---------------Test Result -----------------------
            Assert.AreEqual(0, dmSolution.AllClasses.Count);
            Assert.IsTrue(assembly.Status.IsDeleted);
        }



        [Test]
        public void Test_Revert_AssemblyNameNotFound()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            string assemblyName = "Assembly2";
            ICommand command = CommandFactory.CreateCreateAssembly(dmSolution, assemblyName);
            command.Apply();

            DMAssembly assembly = dmSolution.Assemblies[0];
            assembly.AssemblyName = "ChangedName";

            //---------------Assert Precondition----------------
            Assert.IsFalse(assembly.Status.IsNew);

            //---------------Execute Test ----------------------
            HabaneroDeveloperException exception = null;
            try
            {
                command.Revert();
            }
            catch (HabaneroDeveloperException ex)
            {
                exception = ex;
            }

            //---------------Test Result -----------------------
            Assert.IsNotNull(exception, "HabaneroDeveloperException expected");
            string expectedMessage = string.Format("Error reverting change. Assembly with the name '{0}' not found to remove from solution '{1}'.", assemblyName, dmSolution.SolutionName);
            Assert.AreEqual(expectedMessage, exception.Message);
        }


        private DMSolution CreateSolutionWithNoAssemblies()
        {
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            dmSolution.DefaultAssembly.MarkForDelete();
            dmSolution.DefaultAssembly.Save();
//            dmSolution.Assemblies.MarkForDelete(dmSolution.DefaultAssembly);
//            dmSolution.Save();
            return dmSolution;
        }


    }
}
